package com.itheima.d2_reflect;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/*
     目标：掌握获取类的成员变量，并对其进行操作。

     Class类中方法
        public Field[] getFields()	获取类的全部成员变量（只能获取public修饰的）
        public Field[] getDeclaredFields()	获取类的全部成员变量（只要存在就能拿到）
        public Field getField(String name)	获取类的某个成员变量（只能获取public修饰的）
        public Field getDeclaredField(String name)	获取类的某个成员变量（只要存在就能拿到）
    Field类中的方法
        void set(Object obj, Object value)：	赋值
        Object get(Object obj)	取值
        public void  setAccessible(boolean flag)	设置为true，表示禁止检查访问控制（暴力反射）

   需求 : 操作猫类的成员变量
 */
public class Test3Field {
    @Test
    public void testGetFields() throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class cat = Cat.class;

        // 1. 获取构造器
        final Constructor declaredConstructor = cat.getDeclaredConstructor();

        // 2. 获取所有成员变量
        final Field[] declaredFields = cat.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("成员变量 -> " + declaredField);
        }

        // 3. 获取成员变量 a
        final Field a = cat.getDeclaredField("a");
        System.out.println("a -> " + a);

        // 4. 给静态变量a赋值
        a.set(null, 111);
        System.out.println(a.get(null));

        // 5. 获取私有成员变量
        final Object catObj = declaredConstructor.newInstance();

        final Field name = cat.getDeclaredField("name");
        name.setAccessible(true);
        System.out.println("name -> " + name.get(catObj));

        // 6. 修改值
        name.set(catObj, "初始话name");
        System.out.println("name -> " + name.get(catObj));


    }
}
